package com.gitee.wsl.time.calendar.data


import com.gitee.wsl.time.calendar.Calendar
import com.gitee.wsl.time.calendar.bean.CalendarDay
import com.gitee.wsl.time.calendar.bean.Week
import com.gitee.wsl.time.calendar.style.DayPosition
import com.gitee.wsl.time.daysUntil
import com.gitee.wsl.time.firstDayOfWeekBySystem
import com.gitee.wsl.time.minusDays
import com.gitee.wsl.time.plusDays
import com.gitee.wsl.time.plusWeeks
import com.gitee.wsl.time.weeksUntil
import kotlinx.datetime.DateTimeUnit
import kotlinx.datetime.DayOfWeek
import kotlinx.datetime.LocalDate
import kotlinx.datetime.until


data class WeekData(
    private val firstDayInWeek: LocalDate,
    private val desiredStartDate: LocalDate,
    private val desiredEndDate: LocalDate,
) {
    val week: Week = Week((0 until 7).map { dayOffset -> getDay(dayOffset) })

    private fun getDay(dayOffset: Int): CalendarDay {
        val date = firstDayInWeek.plusDays(dayOffset)
        val position = when {
            date < desiredStartDate -> DayPosition.InDate
            date > desiredEndDate -> DayPosition.OutDate
            else -> DayPosition.RangeDate
        }
        return CalendarDay(date, position)
    }
}

 data class WeekDateRange(
    val startDateAdjusted: LocalDate,
    val endDateAdjusted: LocalDate,
)

 fun Calendar.Companion.getWeekCalendarAdjustedRange(
    startDate: LocalDate,
    endDate: LocalDate,
    firstDayOfWeek: DayOfWeek = firstDayOfWeekBySystem(),
): WeekDateRange {
    val inDays = firstDayOfWeek.daysUntil(startDate.dayOfWeek)
    val startDateAdjusted = startDate.minusDays( inDays)
    val weeksBetween = startDateAdjusted.until(endDate,DateTimeUnit.WEEK)
    //val weeksBetween = ChronoUnit.WEEKS.between(startDateAdjusted, endDate).toInt()
    val endDateAdjusted = startDateAdjusted.plusWeeks(weeksBetween).plusDays(6)
    return WeekDateRange(startDateAdjusted = startDateAdjusted, endDateAdjusted = endDateAdjusted)
}

 fun Calendar.Companion.getWeekCalendarData(
    startDateAdjusted: LocalDate,
    offset: Int = 0,
    desiredStartDate: LocalDate,
    desiredEndDate: LocalDate,
): WeekData {
    val firstDayInWeek = startDateAdjusted.plusWeeks(offset)
    return WeekData(firstDayInWeek, desiredStartDate, desiredEndDate)
}


fun Calendar.Companion.getWeekIndex(startDateAdjusted: LocalDate, date: LocalDate): Int {
    return startDateAdjusted.weeksUntil(date)
}

fun Calendar.Companion.getWeekIndicesCount(startDateAdjusted: LocalDate, endDateAdjusted: LocalDate): Int {
    // Add one to include the start week itself!
    return getWeekIndex(startDateAdjusted, endDateAdjusted) + 1
}
